﻿using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using MolyMade.Moly.HttpRequest.DataTypes;

namespace MolyMade.Moly.HttpRequest.Base
{
    public class BaseRequest
    {
        private HttpWebRequest _httpWebRequest = null;
        private Request _request;
        private Stopwatch _stopwatch = new Stopwatch();

        public IPEndPoint IpEndPoint { get; set; }
        public Encoding Encoding { get; set; }
        public Encoding PostDataEncoding { get; set; }
        public string Url { get; set; }
        public DecompressionMethods DecompressionMethods { get; set; }
        public string CerPath { get; set; }
        public string CerPwd { get; set; }
        public X509CertificateCollection X509CertificateCollection { get; set; }
        public WebHeaderCollection HeaderCollection { get; set; }
        public string Proxy { get; set; }
        public string ProxyUserName { get; set; }
        public string ProxyPassword { get; set; }
        public Version ProtoVersion { get; set; }
        public bool Expect100Continue { get; set; }
        public string HttpMethod { get; set; }
        public int ConnectionTimeout { get; set; }
        public bool KeepAlive { get; set; }
        public int ReadWriteTimeout { get; set; }
        public string Host { get; set; }     
        public DateTime IfModifiedSince { get; set; } 
        public string Accept { get; set; }      
        public string ContentType { get; set; }  
        public string UserAgent { get; set; }
        public ICredentials Credentials { get; set; }
        public CookieCollection CookieCollection { get; set; }    
        public string Referer { get; set; }
        public bool AllowAutoRedirect { get; set; } 
        public int MaxAutoRedirection { get; set; } 
        public int MaxConnection { get; set; }
        public byte[] PostBuffer { get; set; }
        public string Connection { get; set; }
        public long ContentLength { get; set; }
        public DateTime Date { get; set; }
        public string Expect { get; set; }
        public TimeSpan Elasped => _stopwatch.Elapsed; 



        public HttpWebResponse GetResponse()
        {
            //设置请求
            MakeRequest();
            //进行请求
            _stopwatch.Start();
            HttpWebResponse response = (HttpWebResponse) _httpWebRequest.GetResponse();
            _stopwatch.Stop();
            return response;
        }

        public void MakeRequest()
        {
            if (this.Connection != null)
            {
                _httpWebRequest.Connection = this.Connection;
            }
            if (this.Date != DateTime.MinValue)
            {
                _httpWebRequest.Date = this.Date;
            }
            if (this.Expect != null)
            {
                _httpWebRequest.Expect = this.Expect;
            }
            //证书验证
            ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true;
            //创建请求
            _httpWebRequest = (HttpWebRequest) WebRequest.Create(Url);
            //出口端点
            if (IpEndPoint != null)
            {
                _httpWebRequest.ServicePoint.BindIPEndPointDelegate = (point, endPoint, count) => IpEndPoint;
            }
            //压缩形式
            _httpWebRequest.AutomaticDecompression = DecompressionMethods;
            //添加文件证书
            if (!string.IsNullOrWhiteSpace(CerPath))
            {
                _httpWebRequest.ClientCertificates.Add(!string.IsNullOrWhiteSpace(CerPwd)
                    ? new X509Certificate(CerPath, CerPwd)
                    : new X509Certificate(CerPath));
            }
            //添加证书集
            if (X509CertificateCollection != null && X509CertificateCollection.Count > 0)
            {
                _httpWebRequest.ClientCertificates.AddRange(X509CertificateCollection);
            }
            //添加头部
            if (HeaderCollection != null && HeaderCollection.Count > 0)
            {
                foreach (string key in HeaderCollection.AllKeys)
                {
                        _httpWebRequest.Headers.Add(key,HeaderCollection[key]);
                }
            }
            //设置代理
            if (!string.IsNullOrWhiteSpace(Proxy)&&Proxy.Contains(":"))
            {
                string[] plist = Proxy.Split(':');
                WebProxy proxy = new WebProxy(plist[0].Trim(),int.Parse(plist[1].Trim()));
                if (string.IsNullOrWhiteSpace(ProxyUserName))
                {
                    proxy.Credentials = new NetworkCredential(ProxyUserName,ProxyPassword);
                }
                _httpWebRequest.Proxy = proxy;
            }
            //http版本
            if (ProtoVersion != null)
            {
                _httpWebRequest.ProtocolVersion = ProtoVersion;
            }
            //100Continue
            if (!Expect100Continue)
            {
                _httpWebRequest.ServicePoint.Expect100Continue = Expect100Continue;
            }
            //Method
            _httpWebRequest.Method = HttpMethod;
            //连接超时
            if (ConnectionTimeout > 0)
            {
                _httpWebRequest.Timeout = ConnectionTimeout;
            }
            //KeepAlive
            if (!KeepAlive)
            {
                _httpWebRequest.KeepAlive = KeepAlive;
            }
            //读写超时
            if (ReadWriteTimeout > 0)
            {
                _httpWebRequest.ReadWriteTimeout = ReadWriteTimeout;
            }
            //Host
            if (!string.IsNullOrWhiteSpace(Host))
            {
                _httpWebRequest.Host = Host;
            }
            //IfModifiedSince
            if (IfModifiedSince!=DateTime.MinValue)
            {
                _httpWebRequest.IfModifiedSince = this.IfModifiedSince;
            }
            //Accept
            if (Accept != null)
            {
                _httpWebRequest.Accept = Accept;
            }
            //ContentType
            if (ContentType != null)
            {
                _httpWebRequest.ContentType = ContentType;
            }
            //UserAgent
            if (UserAgent != null)
            {
                _httpWebRequest.UserAgent = UserAgent;
            }
            //验证
            if (Credentials != null)
            {
                _httpWebRequest.Credentials = Credentials;
            }
            //Cookie
            _httpWebRequest.CookieContainer = new CookieContainer();
            if (CookieCollection != null && CookieCollection.Count > 0)
            {
                _httpWebRequest.CookieContainer.Add(CookieCollection);
            }
            //Referer
            if (Referer != null)
            {
                _httpWebRequest.Referer = Referer;
            }
            //自动跳转
            if (!AllowAutoRedirect)
            {
                _httpWebRequest.AllowAutoRedirect = AllowAutoRedirect;
            }
            //跳转上限
            if (MaxAutoRedirection > 0)
            {
                _httpWebRequest.MaximumAutomaticRedirections = MaxAutoRedirection;
            }
            //最大连接
            if (MaxConnection > 0)
            {
                _httpWebRequest.ServicePoint.ConnectionLimit = MaxConnection;
            }
            //POST数据
            if (PostBuffer!= null && PostBuffer.Length > 0)
            {
                _httpWebRequest.ContentLength = PostBuffer.Length;
                using (Stream postStream = _httpWebRequest.GetRequestStream())
                { 
                    postStream.Write(PostBuffer,0,PostBuffer.Length);
                }
            }
       }

    }
}
